/*
 Copyright (C) 2010 Chris Hawkins. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 
 * Redistributions of source code must retain the above copyright notice, this
 list of conditions and the following disclaimer.
 
 * Neither the name of the author nor the names of its contributors may be used
 to endorse or promote products derived from this software without specific
 prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import "DataAttribute.h"
#import "AsdUtil.h"

typedef struct {
    unsigned short      code;
    NSString*           name;
    bool                consistentValue;
    bool                multipleValues;
    NSString*           description;
} stDASDAttributeItem;
stDASDAttributeItem astDASDAttributes[] = {
    { eDASDAttribute_ALL            ,@"ALL"              ,false,false,@"Act on all Attributes, not a single selection" },
    { eDASDAttribute_UniqueInteger  ,@"UniqueInteger"    ,true ,false,@"Unique Positve Integer - like a simple ID" },
    { eDASDAttribute_UniqueMixedKey ,@"UniqueMixedKey"   ,true ,false,@"Unique MixedCharacter Key - like a product nubmer" },
    { eDASDAttribute_UniqueRowNumber,@"UniqueRowNumber"  ,true ,false,@"Row Number (from 0)" },
    { eDASDAttribute_Color          ,@"Color"            ,true ,false,@"One of Eight Colors" },
    { eDASDAttribute_Fruit          ,@"Fruit"            ,true ,false,@"Fruit (multiple varieties of same fruit)" },
    { eDASDAttribute_LongText       ,@"LongText"         ,true ,false,@"Long Text - up to max attribute length" },
    { eDASDAttribute_Timestamp_Last ,@"UpdateLast"       ,false,false,@"Timestamp - last update" },
    { eDASDAttribute_Timestamp_Hist ,@"UpdateHistory"    ,false,true ,@"Timestamps of all updates" },
};

@implementation DASDAttribute
#pragma mark -- private handlers based on eDASDAttribute
- (NSString*)           uniqueIntegerForRow: (NSUInteger) rowNumber_ {
    switch ( rowNumber_ % 4 ) {
        case 0:     return [NSString stringWithFormat:@"%u",(rowNumber_ * 10000) + 789];
        case 1:     return [NSString stringWithFormat:@"%u",(rowNumber_ * 1000000) + 456];
        case 2:     return [NSString stringWithFormat:@"%u",((rowNumber_ * 1000) + 123 )];
        default:    break;
    }
    return [NSString stringWithFormat:@"%u",rowNumber_];
}
- (NSString*)           uniqueMixedKeyForRow: (NSUInteger) rowNumber_ {
    switch ( rowNumber_ % 4 ) {
        case 0:     return [NSString stringWithFormat:@"%uGH %u"   ,rowNumber_,(rowNumber_ % 5)];
        case 1:     return [NSString stringWithFormat:@"%uJU98%u88",rowNumber_,(rowNumber_ + 1)];
        case 2:     return [NSString stringWithFormat:@"%u#FDMMM%u",rowNumber_,((rowNumber_ * 1000) + rowNumber_)];
        default:    break;
    }
    return [NSString stringWithFormat:@"%uPZ-00-H88%u",rowNumber_,(rowNumber_ *2)];
}
- (NSString*)           uniqueRowNumberForRow: (NSUInteger) rowNumber_ {
    return [NSString stringWithFormat:@"%u",rowNumber_];
}
- (NSString*)           colorForRow: (NSUInteger) rowNumber_ {
    NSString    *color = @"Blue";
    switch ( rowNumber_ % 12 ) {
        case  0:    color   = @"Brown";     break;
        case  1:                            break;
        case  2:    color   = @"Clear";     break;
        case  3:    color   = @"Dark Gray"; break;
        case  4:    color   = @"Orange";    break;
        case  5:    color   = @"Red";       break;
        case  6:    color   = @"Yellow";    break;
        case  7:    color   = @"Green";     break;
        case  8:    color   = @"White";     break;
        case  9:                            break;
        case 10:    color   = @"Aqua";      break;
        case 11:    color   = @"Black";     break;
        default:                            break;
    }
    return color;
}
- (NSString*)           longTextForRow: (NSUInteger) rowNumber_ {
    NSMutableString *buffer = [[NSMutableString alloc] initWithCapacity: 1000];
    [buffer appendFormat: @"%u-",rowNumber_];
    if ( 5 == ( rowNumber_ % 6 )) {
        [buffer appendString: @"Apple provides a complete ecosystem for developers. All the components including hardware, the operating systems, and the developer tools are designed by one company, and they are all designed to work together seamlessly, creating an easier, more intuitive experience so developers can focus on making great applications."];
    }
    if ( 3 == ( rowNumber_ % 4 )) {
        [buffer appendString: @"Amazon SimpleDB is a highly available, scalable, and flexible non-relational data store that offloads the work of database administration. Developers simply store and query data items via web services requests, and Amazon SimpleDB does the rest. "];
    }
    if ( 0 == ( rowNumber_ % 5 )) {
        [buffer appendString: @" (BLUE COLOR TAG) "];
    }
    if ( 0 == ( rowNumber_ % 3 )) {
        [buffer appendString: @"Digits 1 2 3 4 5 6 7 8 9 0 Digits."];
    }
    if ( 8 == ( rowNumber_ % 10 )) {
        [buffer appendString: @"ABCDEF GHIJKL MNOPQR STUVWXYZ abcdef ghijkl mnopqrs tuvwxyz"];
    }
    if ( 1 == ( rowNumber_ %  6 )) {
        [buffer appendString: @"Objective-C is a reflective, object-oriented programming language which adds Smalltalk-style messaging to the C programming language."];
    }
    if ( 1 == ( rowNumber_ % 7 )) {
        [buffer appendString: @"A formal protocol is similar to an interface in Java or C#. It is a list of methods which any class can declare itself to implement. Versions of Objective-C before 2.0 required that a class must implement all methods in a protocol it declares itself as adopting; the compiler will emit an error if the class does not implement every method from its declared protocols. Objective-C 2.0 added support for marking certain methods in a protocol optional, and the compiler will not enforce implementation of optional methods."];
    }
    if ( 2 == ( rowNumber_ % 8 )) {
        [buffer appendString: @"Issaquah is an anglicized word for a local Native American name, meaning 'the sound of birds'. Another version of the name is said to have come from the pioneers, who, being impressed with the multitude of wetland birds, called the area Squak Valley. When the next wave of settlers came and asked for the name of area the Natives told them, 'Is Squak.'"];
    }
    if ( 3 == ( rowNumber_ % 4 )) {
        [buffer appendString: @"The Darigold trademark was established in 1925 when the United Dairyman's Association offered a prize at its June members' picnic for the best name for its products and the Darigold name was chosen."];
    }
    if ( [buffer length] < 200 ) {
        [buffer appendString: @"It's show time folks. What, still now enough text ? "];
    }
    if ( 1 == ( rowNumber_ % 4 )) {
        [buffer appendString: @" (RED COLOR TAG) "];
    }
    if ( [buffer length] > 1000 ) {
        [buffer deleteCharactersInRange: NSMakeRange( 1000, [buffer length] - 1000)];
        [buffer appendString: @"-TRUNCATED"];
    }
    [buffer appendFormat: @"-%u",rowNumber_];
    NSString        *string = [NSString stringWithString: buffer];
    [buffer release];
    return string;
}
- (NSString*)           fruitForRow: (NSUInteger) rowNumber_ {
    switch ( rowNumber_ % 20 ) {
        case  0:     return @"Gala Apple";
        case  1:     return @"Fuji Apple";
        case  2:     return @"Red Delicous Apple";
        case  3:     return @"Golden Plum";
        case  4:     return @"Damson Plum";
        case  5:     return @"Serbian Plum";
        case  6:     return @"Satsuma Plum";
        case  7:     return @"Guava";
        case  8:     return @"Pineapple";
        case  9:     return @"Durian";
        case 10:     return @"Jackfruit";
        case 11:     return @"Apricot";
        case 12:     return @"Banana";
        case 13:     return @"Abiu";
        case 14:     return @"Granny Smith Apple";
        case 15:     return @"Avacado";
        case 16:     return @"Sour Cherry";
        case 17:     return @"Korean Cherry";
        case 18:     return @"Alabama Cherry";
        case 19:     return @"Bing Cherry";
        case 20:     return @"Chokecherry";
        case 21:     return @"Spring Cherry";
        case 22:     return @"Yoshine Cherry";
        case 23:     return @"Peach";
        case 24:     return @"Nectarine";
        case 25:     return @"Tamarillo";
        case 26:     return @"Walnut";
        case 27:     return @"Cashew";
        case 28:     return @"Lemon";
        case 29:     return @"Lime";
    }
    return @"Orange";
}
- (NSString*)           timeStamp {
    static NSDateFormatter *format = nil;
    if ( format == nil ) {
        @synchronized( [self class] ) {
            if ( format == nil ) {
                format = [[ASDSpUtil awsGmtDateFormatter] retain];
            }
        }
    }
    return [format stringFromDate: [NSDate date]];
}
#pragma mark -- public methods
@synthesize multipleValues = multiple_Values, consistentValue = consistent_Value;

- (NSString*)           valueForRow: (NSUInteger) rowNumber_ {
    switch ( [[self entryCode] intValue] ) {
        case eDASDAttribute_UniqueInteger:
            return [self uniqueIntegerForRow: rowNumber_];
        case eDASDAttribute_UniqueMixedKey:
            return [self uniqueMixedKeyForRow: rowNumber_];
        case eDASDAttribute_UniqueRowNumber:
            return [self uniqueRowNumberForRow: rowNumber_];
        case eDASDAttribute_Color:
            return [self colorForRow: rowNumber_];
        case eDASDAttribute_Fruit:
            return [self fruitForRow: rowNumber_];
        case eDASDAttribute_LongText:
            return [self longTextForRow: rowNumber_];
        case eDASDAttribute_Timestamp_Last:
        case eDASDAttribute_Timestamp_Hist:
            return [self timeStamp];
        case eDASDAttribute_ALL:
            return @"eDASDAttribute_ALL is not valid";
        case eDASDAttribute_INVALID:
            return @"eDASDAttribute_INVALID is not valid";
        default:
            break;
    }
    return [NSString stringWithFormat: @"Row %u-%@",rowNumber_,[self entryName]];
}
#pragma mark -- Global Dictionary
+ (DASDDictionary*)     dictionary {
    static DASDDictionary   *dictAttribute = nil;
    if ( dictAttribute == nil ) {
        @synchronized( self ) {
            if ( dictAttribute == nil ) {
                dictAttribute = [[DASDDictionary alloc] initWithCapacity: mASDarrayCount( astDASDAttributes )];
                stDASDAttributeItem *cur = &astDASDAttributes[0];
                for ( int count = 0; count < mASDarrayCount( astDASDAttributes ); count++, cur++ ) {
                    DASDAttribute *attribute = [[DASDAttribute alloc] initWithCodeInt: cur->code name: cur->name desc: cur->description ];
                    [attribute setConsistentValue: cur->consistentValue];
                    [attribute setMultipleValues:  cur->multipleValues];
                    [dictAttribute addEntry: attribute];
                    [attribute release];
                }
            }
        }
    }
    return dictAttribute;
}

@end
